package com.tinyideatech.wechat.controller;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.github.binarywang.wxpay.bean.notify.WxPayNotifyResponse;
import com.github.binarywang.wxpay.bean.notify.WxPayOrderNotifyResult;
import com.github.binarywang.wxpay.bean.request.WxPayUnifiedOrderRequest;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.tinyideatech.common.core.controller.BaseController;
import com.tinyideatech.common.core.entity.ApiResult;
import com.tinyideatech.common.utils.IpUtils;
import com.tinyideatech.common.utils.http.HttpClientUtil;
import com.tinyideatech.framework.dto.FTP;
import com.tinyideatech.system.entity.*;
import com.tinyideatech.system.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.java.Log;

import org.apache.http.NameValuePair;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.tinyideatech.common.core.entity.ApiResult.warn;

@Log
@RestController
@RequestMapping("/ws/v2/api/pay")
@Api("商城支付接口")
public class PayController extends BaseController {
    private static List<Long> wxPayCache = new ArrayList<Long>();

    @Autowired
    private IMallCarouselService carouselService;
    @Autowired
    private IMallGoodsService goodsService;
    @Autowired
    private IMallCartService cartService;
    @Autowired
    private IMallClassifyService classifyService;
    @Autowired
    private IMallMemberService memberService;
    @Autowired
    private IMallOrderService orderService;
    @Autowired
    private IMallOrderItemService orderItemService;
    @Autowired
    private IMallPayService payService;
    @Autowired
    private WxPayService wxPayService;

    @Autowired
    private ICarModelService modelService;

    @Autowired
    private ICarDeviceService deviceService;

    @Value("${tinyideatech.host}")
    private String host;

    @Value("${url.xinyao}")
    private String xinyaoServiceUrl;

    @Autowired
    private FTP ftpCatalog;

    private static final String USER_ID = "user_id";
    private static final String NOTIFY_URL = "/ws/v2/api/pay/notifyOrder";

    @ApiOperation("商城车模下单接口")
    @RequestMapping(value = "/createOrder/{id}")
    public ApiResult getJSSDKPayInfo(HttpSession session, @PathVariable("id") Long id, HttpServletResponse response,
            HttpServletRequest request) {
        MallOrder order = orderService.getById(id);
        if (order == null) {
            return error("order is not exist");
        }
        if (order.getTotalPrice() == 0) {
            return error("order price is not allowed 0");
        }
        /*
         * orderItemService.list(new QueryWrapper<MallOrderItem>().eq("order_id",
         * order.getOrderId()));
         */
        Long userId = (Long) session.getAttribute(USER_ID);
        MallMember member = memberService.getById(userId);
        if (member == null || member.getOpenId() == null) {
            return error("please login");
        }
        WxPayUnifiedOrderRequest prepayInfo = WxPayUnifiedOrderRequest.newBuilder().openid(member.getOpenId())
                .outTradeNo(order.getOrderId() + "").totalFee((int) (order.getTotalPrice() * 100))
                .body(order.getUserId() + "").tradeType("JSAPI").spbillCreateIp(IpUtils.getRealIp(request))
                .notifyUrl(host + NOTIFY_URL).build();
        log.info(host + NOTIFY_URL);
        try {
            Object payInfo = wxPayService.createOrder(prepayInfo);
            log.info(JSONObject.toJSONString(payInfo));
            return success(payInfo);
        } catch (WxPayException e) {
            return error(e.getErrCodeDes());
        }
    }

    @PostMapping("/notifyOrder")
    @ApiOperation("商城微信支付回调接口")
    public String parseOrderNotifyResult(@RequestBody String xmlData) throws WxPayException {
        try {
            final WxPayOrderNotifyResult result = wxPayService.parseOrderNotifyResult(xmlData);
            Long orderId = Long.parseLong(result.getOutTradeNo());
            if (wxPayCache.contains(orderId)) {
                return WxPayNotifyResponse.fail("回调消息已被处理。");
            } else {
                wxPayCache.add(orderId);
                if (wxPayCache.size() > 1000) {
                    wxPayCache.remove(0);
                }
            }

            List<CarModel> carModelList = new ArrayList<>();
            MallOrder order = orderService.getById(orderId);
            if (order.getPaymentResult() == null || order.getPaymentResult().equals("0")) {
                Collection<MallOrderItem> orderItemList = orderItemService
                        .list(new QueryWrapper<MallOrderItem>().eq("order_id", order.getOrderId()));
                for (MallOrderItem item : orderItemList) {
                    CarModel model = new CarModel();
                    model.setMemberId(order.getUserId());
                    model.setModelId(item.getGoodsId() + "");
                    model.setDeviceId(order.getDeviceId());
                    model.setModelName(item.getGoodsName());
                    MallGoods goods = goodsService.getById(item.getGoodsId());
                    if (goods != null) {
                        model.setModelUrl(goods.getUrl());
                        model.setMd5(goods.getMd5());
                        if (goods.getVolume() == null) {
                            goods.setVolume(1);
                        } else {
                            goods.setVolume(goods.getVolume() + 1);
                        }
                        goodsService.updateById(goods);
                    }
                    carModelList.add(model);

                    // 设置鑫钥授权
                    String clientId = order.getDeviceId();
                    String path = xinyaoServiceUrl + "/service/open";
                    Map<String, String> params = new HashMap<>();
                    params.put("clientId", clientId);
                    params.put("featureGroup", "model");
                    params.put("featureName", item.getGoodsId().toString());
                    params.put("term", "12");
                    List<NameValuePair> paramsList = HttpClientUtil.getParams(params);
                    JSONObject http = HttpClientUtil.sendPost(path, paramsList, null);
                    if (http.getString("status").equals("200")) {
                        log.info("开通服务授权成功！");
                    } else {
                        log.warning("开通服务授权失败！");
                    }
                }
                if (carModelList.size() > 0) {
                    log.info(carModelList.get(0).toString());
                    modelService.saveBatch(carModelList);
                }
                MallPay pay = new MallPay();
                pay.setOrderId(order.getOrderId());
                pay.setUserId(order.getUserId());
                pay.setSize(order.getSize());
                pay.setDeviceId(order.getDeviceId());
                pay.setUsername(order.getUsername());
                pay.setPrice((result.getTotalFee() * 1.0 / 100));
                payService.save(pay);
                log.info(pay.toString());
                order.setPaymentResult("1");
                order.setPaymentTime(new Date());
                orderService.updateById(order);
                MallMember mallMember = memberService.getById(order.getUserId());
                if (mallMember != null) {
                    if (mallMember.getGroupId() == null) {
                        mallMember.setGroupId(0);
                    }
                    int num = mallMember.getGroupId() + carModelList.size();
                    mallMember.setGroupId(num);
                    // 2019-10-31 统计同一微信用户下的金额
                    mallMember.setDeviceId(order.getDeviceId());
                    mallMember.setSum(mallMember.getSum() + (result.getTotalFee() * 1.0 / 100));
                    log.info(mallMember.toString());
                    memberService.updateById(mallMember);
                    CarDevice device = deviceService.getById(order.getDeviceId());
                    if (device != null) {
                        device.setMemberId(mallMember.getMemberId());
                        // 2019-10-31 设置车模数量
                        device.setDeviceModelNum(num);
                        deviceService.updateById(device);
                    }
                }
            }
            return WxPayNotifyResponse.success("成功");
        } catch (Exception e) {
            return WxPayNotifyResponse.fail(e.getMessage());
        }
    }

    /**
     * 车模功能订单校验
     *
     * @param deviceId
     * @return
     */
    @RequestMapping("/verify/order")
    @ApiOperation("车机验证商城车模下载队列接口")
    public ApiResult modelByDeviceId(@RequestParam String deviceId) {
        List<CarDevice> deviceList = deviceService.list(new QueryWrapper<CarDevice>().eq("device_id", deviceId));
        if (deviceList.size() != 1) {
            return warn("vehicle is not exist");
        }
        // .le("upload_size", 3))
        List<CarModel> modelList = modelService
                .list(new QueryWrapper<CarModel>().eq("device_id", deviceId).eq("del_flag", 1));
        if (modelList.size() == 0) {
            return warn("no order to bind");
        }
        CarModel model = modelList.get(0);
        JSONObject obj = new JSONObject();
        obj.put("modelId", model.getModelId());
        String ftpUrl = ftpCatalog.getFullPathMODFtp() + model.getModelUrl();
        obj.put("url", ftpUrl);
        obj.put("md5", model.getMd5());
        modelService.removeById(model.getId());
        return success(obj);
    }
}
